package com.zhen.aikan.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.gson.JsonPrimitive;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDate;
import java.util.*;

/**
 * @author LiJiaZhen
 * @date 2023/11/9 14:03
 * @describe GitHub图床工具类
 */
@Slf4j
@Component
public class GitHubFileUtil {

    public static final String URI_SEPARATOR = "/";

    public static final Set<String> ALLOW_FILE_SUFFIX = new HashSet<>(Arrays.asList("jpg", "png", "jpeg", "gif"));

    private static String url;

    private static String api;

    private static String accessToken;

    private static String branch;

    @Value("${github.bucket.url}")
    public void setUrl(String url) {
        GitHubFileUtil.url = url;
    }

    @Value("${github.bucket.api}")
    public void setApi(String api) {
        GitHubFileUtil.api = api;
    }

    @Value("${github.bucket.access-token}")
    public void setAccessToken(String accessToken) {
        GitHubFileUtil.accessToken = accessToken;
    }

    @Value("${github.bucket.branch}")
    public void setBranch(String branch) {
        GitHubFileUtil.branch = branch;
    }

    /**
     * 上传文件
     *
     * @param file    文件地址
     * @param message 提交描述
     * @return 文件访问地址
     */
    public static String uploading(MultipartFile file, String message) throws IOException {
        String suffix = getSuffix(Objects.requireNonNull(file.getOriginalFilename())).toLowerCase();
        if (!ALLOW_FILE_SUFFIX.contains(suffix)) {
            throw new IllegalArgumentException("不支持的文件后缀：" + suffix);
        }
        // 重置文件名防止重复
        String fileName = UUID.randomUUID().toString().replace("-", "") + "." + suffix;
        JSONObject param = new JSONObject();
        // 提交描述
        param.set("message", message);
        // Base64过的文件
        param.set("content", Base64.getEncoder().encodeToString(file.getBytes()));
        // 上传到仓库的分支，以前是master;2020.10.01开始就变成了main了
        param.set("branch", branch);
//        JSONObject committer = new JSONObject();
        // 提交的作者或提交者的姓名
//        committer.put("name", Param.name);
        // 提交的作者或提交者的电子邮件
//        committer.put("email", Param.email);
//        param.put("committer", committer);

        // 添加的时候没有参数也要写""
        param.set("sha", "");
        String[] dateFolder = getDateFolder();
        String s = "img/" + dateFolder[0] + URI_SEPARATOR + dateFolder[1] + URI_SEPARATOR + dateFolder[2] + URI_SEPARATOR + fileName;
        String apiUrl = api + s;


        HttpResponse response = HttpRequest.put(apiUrl)
                .header("Accept", "application/vnd.github+json")
                .header("Authorization", "token " + accessToken).body(param.toString()).execute();

        if (response.getStatus() != 201) {
            throw new IllegalArgumentException("请求失败！");
        }
        // 返回访问地址
        return url + s;
    }


    /**
     * 查询sha 替换、删除文件时使用
     *
     * @param fileUrl github库中的路径；例：img/xxx.jpg
     * @return sha
     */
    public static String getSha(String fileUrl) {
        String apiUrl = api + fileUrl;

        HttpResponse response = HttpRequest.get(apiUrl)
                .header("Accept", "application/vnd.github+json")
                .header("Authorization", "token " + accessToken).execute();
        log.info("响应结果：{}", response.body());
        JSONObject result = new JSONObject(response.body());
        return result.getStr("sha");
    }


    /**
     * 获取文件的后缀
     *
     * @param fileName
     * @return
     */
    protected static String getSuffix(String fileName) {
        int index = fileName.lastIndexOf(".");
        if (index != -1) {
            String suffix = fileName.substring(index + 1);
            if (!suffix.isEmpty()) {
                return suffix;
            }
        }
        throw new IllegalArgumentException("非法的文件名称：" + fileName);
    }

    /**
     * 按照年月日获取打散的打散目录
     * yyyy/mmd/dd
     *
     * @return
     */
    protected static String[] getDateFolder() {
        String[] retVal = new String[3];

        LocalDate localDate = LocalDate.now();
        retVal[0] = localDate.getYear() + "";

        int month = localDate.getMonthValue();
        retVal[1] = month < 10 ? "0" + month : month + "";

        int day = localDate.getDayOfMonth();
        retVal[2] = day < 10 ? "0" + day : day + "";

        return retVal;
    }
}
